package cn.k23.utils;

import cn.k23.bean.TokenVerifyBean;
import cn.k23.config.autoconfig.TokenProperties;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @Description:
 * @Author: k23
 * @Date: 2022-05-10 14:32
 * @Version: 1.0
 */
public class TokenUtils {

    private final String ALGORITHM_NAME="HMAC256"; //默认算法
    private final String ISSUSER="k23"; //默认算法

    @Autowired
    TokenProperties properties;

    /**
     * 生成token字符串
     * @param map 要包含在token公共部分的参数，切记不要包含敏感信息
     * @return taken字符串
     */
    public String generateToken(Map map){
        String token = JWT.create()
                .withHeader(getHeader())
                .withPayload(parsePayload(map))
                .withIssuer(ISSUSER)
                .withExpiresAt(getExpireDate()) //设置过期时间
                .sign(Algorithm.HMAC256(properties.getSecret()));//设置密钥


        return token;
    }

    /**
     * 获取token到期时间
     * @return
     */
    Date getExpireDate(){
        long time=this.properties.getValidateTime()*60*1000;
        return new Date(System.currentTimeMillis()+time);
    }

    /**
     * 验证token
     * @param token  要验证的token字符串
     * @return  TokenVerifyBean code=200 验证成功  其它失败
     */
    public TokenVerifyBean verifyToken(String token){
        JWTVerifier verifier=JWT.require(Algorithm.HMAC256(properties.getSecret()))
                .withIssuer(ISSUSER)
                .build();
        DecodedJWT decodedJWT=null;
        try {
            decodedJWT= verifier.verify(token);
        } catch (TokenExpiredException e){
            return new TokenVerifyBean(2,"token已过期！",null);
        } catch (JWTDecodeException e){
            return new TokenVerifyBean(1,"token无效",null);
        }catch (Exception e){
            e.printStackTrace();
        }
        return new TokenVerifyBean(200,"有效token",decodedJWT.getClaims());
    }


    //验证传来的map是否有空值
    Map parsePayload(Map map){
        Map rsMap=new HashMap();
        //遍历map
        Set<Map.Entry<String,Object>> set= map.entrySet();
        Iterator<Map.Entry<String,Object>> it=set.iterator();
        while(it.hasNext()){
            Map.Entry<String,Object> entry=it.next();
            if(null!=entry.getKey()&&null!=entry.getValue()){
                rsMap.put(entry.getKey(),entry.getValue());
            }
        }
        return rsMap;
    }


    /**
     * 获取token头信息
     * @return
     */
    private Map getHeader(){
        Map map = new HashMap();
        map.put("typ","jwt");
        map.put("alg",ALGORITHM_NAME);
        return  map;
    }


}
